#include <iostream>
#include <ostream>

using std::cout;
using std::endl;

class Data {
public:
    Data(int ix = 0)
    : _ix(ix)
    {   cout << "Data(int)" << endl;    }

    int getData() const 
    {   return _ix;}

    ~Data() {   cout << "~Data()" << endl;  }

private:
    int _ix;
};

class MiddleLayer
{
public:
    MiddleLayer(Data * p)
    : _pdata(p)
    {   cout << "MiddleLayer(Data)" << endl;}

    ~MiddleLayer()
    {   
        cout << "~MiddleLayer()" << endl;
        if(_pdata) {
            delete _pdata;
            _pdata = nullptr;
        }
    }

    Data * getPointer() {   return _pdata;  }

    //当一个类中重载了->和 * 之后，
    //可以间接访问另一个对象
    
    //箭头访问运算符
    Data * operator->()
    {   return _pdata;  }

    //解引用运算符
    Data & operator*()
    {   return *_pdata; }


private:
    Data * _pdata;//指向的是一个堆空间的对象
};

class ThirdLayer
{
public:
    ThirdLayer(MiddleLayer * p)
    : _pml(p)
    {   cout << "ThirdLayer()" << endl;}

    ~ThirdLayer() {
        cout << "~ThirdLayer()" << endl;
        if(_pml) {
            delete _pml;
            _pml = nullptr;
        }
    }

    //第三层如果要实现间接访问Data的对象，就必须要返回的是
    //MiddleLayer的对象
    MiddleLayer & operator->()
    {   return *_pml;    }

private:
    MiddleLayer * _pml;//_pml指向的是一个堆空间的对象
};

int test0()
{
    //通过一个MiddleLayer对象的生命周期来管理一个Data的堆对象
    //ml是一个对象,不是指针
    MiddleLayer ml(new Data(10));
    cout << ml.getPointer()->getData() << endl;
    //简化形式, 看起来又是一个指针
    cout << ml->getData() << endl;
    //完整调用形式
    cout << ml.operator->()->getData() << endl;

    cout << (*ml).getData() << endl;
    //完整调用形式
    cout << (ml.operator*()).getData() << endl;


    return 0;
}

int test1()
{
    ThirdLayer tl(new MiddleLayer(new Data(20)));
    //完整形式
    cout << (tl.operator->().operator->())->getData() << endl;
    //简化形式
    cout << tl->getData() << endl;
    return 0;
}

int main()
{
    test1();
    return 0;
}

